﻿using System;
using System.Collections.Generic;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using ImageProcessing.Utility;
using System.IO;
using System.Web.Services;
using System.Data;

namespace ImageReview
{
    public partial class Process : System.Web.UI.Page
    {
        //public static List<string> replaceImages = new List<string>();
        protected void Page_Load(object sender, EventArgs e)
        {
            Session["ShowDeleteLink"] = true;
            Session["CurrentPage"] = CurrentPage.Process;

            // Determine the user name, less domain
            string username = User.Identity.Name;
            username = username.Substring(username.LastIndexOf('\\') + 1);
            Session["currentUsername"] = username;
            if (Session["ProcessedImageBaseDir"] == null)
            {
                Session["ProcessedImageBaseDir"] = ConfigurationManager.AppSettings["importdir"];
            }



            // Cannot go further without a folder in session state
            if (Session["ProcessedImageBaseDir"] == null)
            {

                Response.Write("<script type=\"text/javascript\">alert('Unable to load the Processed Image Folder.<br/>Check web.config to make sure importdir is correct.');</script>");
                return;
            }

            if (!IsPostBack)
            {
                Label lblUsername = (Label)this.FindControl("lblUsername");
                lblUsername.Text = "User: ";
                Label lblUsername2 = (Label)this.FindControl("lblUsername2");
                lblUsername2.Text = username;
                Session["ProcessedImagesUserDir"] =Session["ProcessedImageBaseDir"] + @"\" + username;
                FolderName.Text = Session["ProcessedImagesUserDir"].ToString();
                Session["ReplacedImages"] = string.Empty;
                LoadImages();
            }
        }

        private bool LoadImages()
        {
            List<FileInfo> files = new List<FileInfo>();
            DirectoryInfo di = new DirectoryInfo(Session["ProcessedImagesUserDir"].ToString());
            try
            {
                foreach (FileInfo item in di.GetFiles())
                {
                    files.Add(item);
                }
            }
            catch (Exception ex)
            {
                Response.Write(string.Format("<script type=\"text/javascript\">alert('Directory {0} \n could not be accessed!');</script>",di.FullName));
                return true ;
            }
            //string result = string.Empty;
            DataTable dt = new DataTable();
            DataRow dr;

            dt.Columns.Add(new DataColumn("PhotoUrl", typeof(string)));
            dt.Columns.Add(new DataColumn("PhotoThumbUrl", typeof(string)));
            dt.Columns.Add(new DataColumn("PhotoName", typeof(string)));

            List<PhotoInfo> images = new List<PhotoInfo>();
            foreach (FileInfo file in files)
            {
                string serverPath = GetServerImagePath(file.FullName);
                string serverthumbPath = GetServerThumbImagePath(file.FullName);
                string filename = GetFileName(file.FullName);
                PhotoInfo info = GetPhotoInfoFromFileName(filename);
                images.Add(info);

                dr = dt.NewRow();
                dr[0] = serverPath;
                dr[1] = serverthumbPath;
                dr[2] = filename;
                dt.Rows.Add(dr);
            }

            DataView dv = new DataView(dt);
            this.imagesResultsList.DataSource = dv;
            this.imagesResultsList.DataBind();

            return LoadConflictImages(images);
        }

        private string Get284Name(string filename)
        {
            int dotIndex = filename.LastIndexOf('.');
            string fileId = filename.Substring(0, dotIndex);
            return fileId + "_284.jpg";
        }
        private bool LoadConflictImages(List<PhotoInfo> newImages)
        {
            DataTable dt = new DataTable();
            DataRow dr;

            dt.Columns.Add(new DataColumn("NewPhotoUrl", typeof(string)));
            dt.Columns.Add(new DataColumn("OriginalPhotoUrl", typeof(string)));
            dt.Columns.Add(new DataColumn("PhotoName", typeof(string)));
            dt.Columns.Add(new DataColumn("OriginalPhotoDateTime", typeof(string)));

            foreach (PhotoInfo item in newImages)
            {
                if (!PhotoIsExcluded(item))
                {
                    Database db = Database.Open(ConfigurationManager.AppSettings["dbname"].ToString());
                    PhotoInfo info = db.CheckPhotoExist(item.GoodID, item.Suffix);
                    if (info.GoodID != null)
                    {
                        //photo already exist in the system
                        //string html = "<tr><td><img src='{0}' style='width:120px;height:80px;'/></td><td><img src='{1}' style='width:120px;height:80px;'/></td><td><a>Replace Original Image</a> &nbsp;&nbsp;<a>Delete New Image</a></td><tr>";
                        string filename = string.Format("{0}{1}.jpg", info.GoodID, info.Suffix);
                        string processedImagePath = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["processedImageRelPath"].ToString(), info.MD5Folder, Get284Name(filename));
                        string newImagePath = string.Format("{0}/{1}/thumb/{2}", ConfigurationManager.AppSettings["outputImageRelPath"].ToString(), Session["currentUsername"].ToString(), filename);
                        //string.Format(html, ResolveClientUrl(newImagePath), ResolveClientUrl(processedImagePath));
                        dr = dt.NewRow();
                        dr[0] = ResolveClientUrl(newImagePath);
                        dr[1] = ResolveClientUrl(processedImagePath);
                        dr[2] = string.Format("{0}{1}", info.GoodID, info.Suffix);
                        dr[3] = info.LoadTime.ToString();
                        dt.Rows.Add(dr);
                    }
                }
            }
            DataView dv = new DataView(dt);
            conflictImagesList.DataSource = dv;
            conflictImagesList.DataBind();

            //check if there is any conflict iamges still not resolved.
            //false if there is still conflict images
            //true if no images in conflict
            if (dt.Rows.Count > 0)
                return false;
            return true;
        }

        private bool PhotoIsExcluded(PhotoInfo item)
        {
            string filename = string.Format("{0}{1}", item.GoodID, item.Suffix);

            foreach (string images in GetReplacedImagesToList())
            {
                if (images.Equals(filename, StringComparison.CurrentCultureIgnoreCase))
                    return true;
            }
            return false;
        }

        private void LoadMatchingPhoto(List<PhotoInfo> images)
        {
            string output = @"<table><tr>";
            bool hasMatchedImages = false;
            foreach (PhotoInfo item in images)
            {
                Database db = Database.Open(ConfigurationManager.AppSettings["dbname"].ToString());
                PhotoInfo info = db.CheckPhotoExist(item.GoodID,item.Suffix);
                if(info != null){
                    //photo already exist in the system
                    string html = "<tr><td><img src='{0}' style='width:120px;height:80px;'/></td><td><img src='{1}' style='width:120px;height:80px;'/></td><td><a>Replace Original Image</a> &nbsp;&nbsp;<a>Delete New Image</a></td><tr>";
                    string filename = string.Format("{0}{1}.jpg",info.GoodID,info.Suffix);
                    string processedImagePath = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["processedImageRelPath"].ToString(),info.MD5Folder,filename);
                    string newImagePath = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["outputImageRelPath"].ToString(), Session["currentUsername"].ToString(), filename);
                    output += string.Format(html, ResolveClientUrl(newImagePath), ResolveClientUrl(processedImagePath));
                    hasMatchedImages = true;
                }
            }
            output += @"</table>";

            if (hasMatchedImages)
            {
                this.matchimages.Visible = true;
                this.matchedImages.Text = output;
            }
            else
            {
                this.matchimages.Visible = false;
            }
        }

        private PhotoInfo GetPhotoInfoFromFileName(string filename)
        {
            //file name: 12345aa.jpg
            //return :12345
            PhotoInfo info = new PhotoInfo();
            int index = filename.LastIndexOf('.') - 2;
            if (index > 0)
            {
                info.GoodID = filename.Substring(0, index);
                info.Suffix = filename.Substring(index, 2);
            }
            return info;
        }

        private string GetServerImagePath(string p)
        {
            string filename = GetFileName(p);
            string outputFolder = ConfigurationManager.AppSettings["outputImageRelPath"].ToString();
            string path = ResolveClientUrl(string.Format("{0}/{1}/{2}", outputFolder, Session["currentUsername"].ToString(), filename));
            return path;
        }

        private string GetServerThumbImagePath(string p)
        {
            string filename = GetFileName(p);
            string outputFolder = ConfigurationManager.AppSettings["outputImageRelPath"].ToString();
            string path = ResolveClientUrl(string.Format("{0}/{1}/thumb/{2}", outputFolder, Session["currentUsername"].ToString(), filename));
            return path;
        }

        private string GetFileName(string p)
        {
            return p.Substring(p.LastIndexOf("\\") + 1, p.Length - p.LastIndexOf("\\") - 1);
        }

        /// <summary>
        /// the process images will 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnProcess_Click(object sender, EventArgs e)
        {
            if (!LoadImages())
            {
                Response.Write("<script type='text/javascript'>alert('Resolve all conflict images before proceed!');</script>");
                return;
            }
            string username = User.Identity.Name;
            username = username.Substring(username.LastIndexOf('\\') + 1);

            string basedir = ConfigurationManager.AppSettings["basedir"];
            string archivedir = ConfigurationManager.AppSettings["archivedir"];
            string importdir = ConfigurationManager.AppSettings["importdir"];
            string dbname = ConfigurationManager.AppSettings["dbname"];
            importdir = string.Format("{0}\\{1}", importdir, username);
            ImagesHandler handler = new ImagesHandler(basedir,importdir, archivedir, dbname);
            string archiveToSPServer = ConfigurationManager.AppSettings["archiveToSharePointServer"];
            bool isArchived = archiveToSPServer == "1";
            
            bool success = handler.ProcessToMD5AndArchiveToTimeFolder(isArchived);
            if (success)
            {
                string message = DeleteAllImagesInOutput();
                LoadImages();
                lblMessage.Text = message + "<div style='font-weight:bold;'><span style='font-size:14px;'>The Process is finished.</span><br><a href='submit.aspx'>Click here to upload more photos</a><br /><a href='search.aspx'>Click here to review photos</a></div>";
            }else
            {
                lblMessage.Text = "<div style='font-weight:bold;'><span style='font-size:14px;'>The Process is is finished with error.</div>";

            }
        }

        private string DeleteAllImagesInOutput()
        {
            string baseDir = Session["ProcessedImagesUserDir"].ToString();

            string output = string.Empty;

            DirectoryInfo di = new DirectoryInfo(baseDir);

            List<string> files = new List<string>();
            try
            {
                foreach (FileInfo item in di.GetFiles())
                {
                    files.Add(item.FullName);
                }
                output = "Total files Processed: " + files.Count + "<br />";
                foreach (string item in files)
                {
                    File.Delete(item);
                }
                DirectoryInfo thumbFolder = di.GetDirectories("thumb")[0];
                if(thumbFolder.Exists)
                {
                    thumbFolder.Delete(true);
                }

            }
            catch (Exception ex)
            {
                output += "Directory can not be accessed!";
            }
            return output;
        }

        protected void conflictImagesList_ItemCommand(object source, DataListCommandEventArgs e)
        {
            string filename = e.CommandArgument.ToString();

            if (e.CommandName == "Delete")
            {
                //delete new photo from the file
                //Response.Write("<script type='text/javascript'>alert('image " + filename + " is deleted.');</script>);");
                DeleteExistingProcessedImages(filename);
                LoadImages();
            }
            else if (e.CommandName == "Replace")
            {
                //mark this new images and remove from the conflict images list
                //Response.Write("<script type='text/javascript'>alert('image " + filename + " is replaced.');</script>);");
                //replaceImages.Add(filename);
                AddReplaceImage(filename);
                LoadImages();
            }
        }
        private void AddReplaceImage(string filename)
        {
            string existingfiles = Session["ReplacedImages"].ToString();
            if (string.IsNullOrEmpty(existingfiles))
            {
                Session["ReplacedImages"] = filename;
            }
            else
            {
                Session["ReplacedImages"] = existingfiles + "," + filename;
            }
        }
        private string[] GetReplacedImagesToList()
        {
            List<string> files = new List<string>();
            string existingfiles = Session["ReplacedImages"].ToString();
            return existingfiles.Split(',');
        }

        private void DeleteExistingProcessedImages(string filename)
        {
            string baseDir = Session["ProcessedImagesUserDir"].ToString();
            string filePath = baseDir + "/" + filename + ".jpg";
            File.Delete(filePath);
        }

        protected void imagesResultsList_ItemCommand(object source, DataListCommandEventArgs e)
        {
            string filename = e.CommandArgument.ToString(); //this filename contains .jpg, need to remove this
            string filevalue = filename.Substring(0, filename.LastIndexOf('.'));

            if (e.CommandName == "Remove")
            {
                DeleteExistingProcessedImages(filevalue);
                LoadImages();
            }
        }
    }
}